package com.bolt.report.engine.export.pdf;

import com.bolt.report.engine.FillElement;
import com.bolt.report.engine.fill.FillChartElement;
import com.bolt.report.engine.fill.FillImageElement;
import com.bolt.report.engine.model.*;
import com.bolt.report.exception.ReportException;
import com.bolt.report.util.ToolUtil;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.List;
import java.util.Map;

@Slf4j
public class PdfExporter extends BasePdfExporter {

    protected Document document;

    protected PdfPTable pdfPTable;

    public PdfExporter() {
        super();
    }

    public PdfExporter(Map<String, Object> parameters) {
        super(parameters);
    }


    @Override
    public void exportReport() throws ReportException {
        initInput();
        outputStream = getExporterOutput().getOutputStream();
        try {
            exportReportTStream();
        } catch (Exception ex) {
            throw new ReportException(ex);
        } finally {
            document.close();
            getExporterOutput().close();
        }
    }

    protected void exportReportTStream() throws ReportException, IOException {
        document = createDocument();
        try {
            PdfWriter.getInstance(document, outputStream);
            document.open();

            exportPage();
        } catch (Exception ex) {
            log.error("export pdf error",ex);
            throw new ReportException(ex);
        }
    }


    protected void exportColumnHeader(ColumnHeader columnHeader) throws DocumentException, IOException {

        exportBand(columnHeader);
    }

    protected void exportPage() throws DocumentException, IOException {
        ColumnHeader columnHeader = reportPrint.getColumnHeader();
        List<PageDetails> pages = reportPrint.getPages();
        Title title = reportPrint.getTitle();

        if (pages != null && pages.size() > 0) {
            PageRange pageRange = getPageRange();
            int startPageIndex = pageRange.getStartPageIndex();
            int endPageIndex = pageRange.getEndPageIndex();
            PageDetails page = null;
            for (; startPageIndex <= endPageIndex; startPageIndex++) {
                page = pages.get(startPageIndex);
                pdfPTable = createPdfTable(page);
                if (title != null && title.isLoopPrintTitle(startPageIndex)) {
                    exportBand(title);
                }
                if (columnHeader != null && columnHeader.isLoopPrintHead(startPageIndex)) {
                    exportBand(columnHeader);
                }
                if (page != null) {
                    exportBand(page);
                }
                document.add(pdfPTable);
                document.newPage();
            }
        }


    }

    private void exportBand(BaseBand baseBand) throws DocumentException, IOException {
        Table table = baseBand.getTable();
        List<Column> columns = table.getColumns();
        List<Row> rows = table.getRows();
        if (columns.isEmpty() || rows.isEmpty()) {
            return;
        }
        for (int r = 0; r < rows.size(); r++) {
            Row row = rows.get(r);
            if (row.isEmpty()) {
                continue;
            }
            for (int c = 0; c < columns.size(); c++) {
                Column col = columns.get(c);
                if (col.isHide()) {
                    continue;
                }
                Cell cell = row.getCell(col);
                if (cell == null) {
                    continue;
                }
                PdfPCell pdfCell = null;
                FillElement element = cell.getElement();
                if (element instanceof FillChartElement) {
                    FillChartElement chartElement = (FillChartElement) element;
                    if (this.parameters.containsKey(chartElement.getChartId())) {
                        com.itextpdf.text.Image img = buildPdfImage((String) getParameter(chartElement.getChartId()), chartElement.getWidth(), chartElement.getHeight());
                        pdfCell = new PdfPCell(img);
                        pdfCell.setBorder(Rectangle.NO_BORDER);
                        pdfCell.setPadding(0);
                    }
                } else if (element instanceof FillImageElement) {
                    FillImageElement imageElement = (FillImageElement) element;
                    com.itextpdf.text.Image img = buildPdfImage(imageElement.getValue(), imageElement.getWidth(), imageElement.getHeight());
                    pdfCell = createCell(cell.getStyle());
                    pdfCell.setImage(img);
                    pdfCell.setCellEvent(new PdfCellBorderEvent(table,cell));
                } else {
                    pdfCell = createCell(cell.getStyle());
                    pdfCell.setCellEvent(new PdfCellBorderEvent(table,cell));
                    pdfCell.setFixedHeight(ToolUtil.pixelToPoint(row.getRealHeight()));
                    pdfCell.setPhrase(createPdfPhrase(cell));

                }

                if (cell.getRowSpan() > 0) {
                    pdfCell.setRowspan(cell.getRowSpan());
                }
                if (cell.getColSpan() > 0) {
                    pdfCell.setColspan(cell.getColSpan());
                }
                pdfPTable.addCell(pdfCell);
            }
        }
    }

}